package Tetris;

import javax.swing.*;
import java.awt.*;
import java.util.Objects;
import java.util.Random;

import static Tetris.Tetris.COLS;
import static Tetris.Tetris.ROWS;

public class Tool {

    public static void draw(int[][] data, JTextArea[][] text,int[][] block, int row, int col){
        for (int i = 0; i < block.length; i++) {
            for (int j = 0; j < block[i].length; j++) {
                if (block[i][j] == 1){
                    data[i + row][j + col] = 1;
                    text[i + row][j + col].setBackground(Color.BLACK);
                }
            }
        }
         //text[row][col].setBackground(Color.RED);
    }

    public static void clear(int[][] data, JTextArea[][] text,int[][] block, int row, int col){
        if(row < 0) return;
        for (int i = 0; i < block.length; i++) {
            for (int j = 0; j < block[i].length; j++) {
                if (block[i][j] == 1){
                    data[i + row][j + col] = 0;
                    text[i + row][j + col].setBackground(Color.WHITE);
                }
            }
        }
    }

    /**
     * @param dir: 获取俄罗斯方块哪个边缘
     * @return 黑色的点的坐标(row,col)
     */
    public static int[][] getEdge(int[][] data, int[][] block, int row, int col, String dir) {

        // 层遍历（左右）
        // 分别在端边，向内遍历，知道找到黑块，然后保存黑块位置


        if (Objects.equals(dir, "BOTTOM")) {
            int bottomRow = row + block.length - 1;
            int[][] black = new int[block[0].length][2];
            for (int i = 0; i < block[0].length; i++) {
                // i --> col遍历
                for (int j = 0; j < block.length; j++) {
                    // j --> 行遍历
                    if (bottomRow - j < 0) break;
                    if (data[bottomRow - j][col + i] == 1 && block[block.length - 1 - j][i] == 1){
                        black[i] = new int[] {bottomRow - j, col + i};
                        break;
                    }
                }
            }
            return black;
        } else if (Objects.equals(dir, "LEFT")) {
            int[][] black = new int[block.length][2];
            if(row + block.length - 1 >= ROWS) return null;
            for (int i = 0; i < block.length; i++) {
                for (int j = 0; j < block[0].length; j++) {
                    if (data[row + i][col + j] == 1) {;
                        black[i] = new int[] {row + i, col + j};
                        break;
                    }
                }
            }
            return black;
        }else if (Objects.equals(dir, "RIGHT")) {
            int[][] black = new int[block.length][2];
            if(row + block.length - 1 >= ROWS) return null;
            for (int i = 0; i < block.length; i++) {
                for (int j = 0; j < block[0].length; j++) {
                    if (data[row + i][col + block[0].length - 1 - j] == 1) {
                        black[i] = new int[] {row + i, col + block[0].length - 1 - j};
                        break;
                    }
                }
            }
            return black;
        }

        return null;
    }

    public static boolean fall(int[][] data,int[][] block, int row, int col){
        if(row + block.length - 1 >= ROWS - 1) return false;
        int[][] black = getEdge(data, block, row, col , "BOTTOM");
        if (black != null) {
            for (int i = 0; i < black.length; i++) {
                int row_x = black[i][0];
                int col_y = black[i][1];
                if(row_x + 1 >= ROWS) return false;
                if (data[row_x + 1][col_y] == 1) return false;
            }
        }
      return true;
    }


    /**
     * @return 随机生成的俄罗斯方块
     */
    public static int[][] getData(){
        return Data.data[new Random().nextInt(Data.data.length)];
    }

    public static int[][] getData(int index){
        return Data.data[index];
    }

    /**
     * 处理的是旋转后的空间中有没有已经是黑块块的地方
     * 如果有，就返回false
     * @param block:当前的图形
     * @param data: 整个游戏的矩阵
     * @param row: 当前图形的行坐标
     * @param col: 当前图形的列坐标
     * @return 是否可以旋转
     */
    private static boolean canRotate(int[][] newBlock,int[][]data, int row, int col){
        for (int i = 0; i < newBlock.length; i++) {
            for (int j = 0; j < newBlock[0].length; j++) {
                if (newBlock[i][j] == 1 && data[row + i][col+j] == 1) return false;
            }
        }
        return true;
    }


    /**
     * 旋转
     * @param block:当前的图形
     * @return 转置后的结果
     */
    public static int[][] rotate(int[][] block,int row, int col,int[][] data) {
        int rows = block.length;
        int cols = block[0].length;
        int[][] newBlock = new int[cols][rows];
        if(row + cols - 1 >= ROWS || col + rows - 1 >= COLS) return null;

        for (int i = 0; i < rows; i++) {
            for (int j = 0; j < cols; j++) {
                newBlock[j][rows - 1 - i] = block[i][j];
            }
        }
        boolean canRotate = canRotate(newBlock,data, row, col);
        if(!canRotate) return null;
        return newBlock;
    }

    public static boolean gameOver(int[][] block,int[][] data, int col){
      return data[block.length - 1][col] == 1;
    }

    public static boolean canMove(int[][] block, int[][] data, int row, int col, String dir){
        // 先得到边缘的黑块坐标，然后检查边缘黑块的旁边是否可以移动
        int[][] black = getEdge(data, block, row, col, dir);
        if (black == null) return false;
        if (Objects.equals(dir, "LEFT")) {
            if(col == 0) return false;
            for (int i = 0; i < black.length; i++) {
                int x = black[i][0];
                int y = black[i][1] - 1;
                if(y < 0) return false;
                if (data[x][y] == 1) return false;
            }
        }else if (Objects.equals(dir, "RIGHT")) {
            if(col + block[0].length - 1 == COLS - 1) return false;
            for (int i = 0; i < black.length; i++) {
                int x = black[i][0];
                int y = black[i][1] + 1;
                if(y >= COLS) return false;
                if (data[x][y] == 1) return false;
            }
        }
        return true;
    }
    public static int moveLeft(int[][] data, JTextArea[][] text,int[][] block, int row, int col){
        if(canMove(block ,data, row, col, "LEFT")){
            clear(data, text, block, row, col);
            col--;
            draw(data, text, block, row, col);
        }
        return col;
    }

    public static int moveRight(int[][] data, JTextArea[][] text,int[][] block, int row, int col){
        if(canMove(block, data, row, col, "RIGHT")){
            clear(data, text, block, row, col);
            col++;
            draw(data, text, block, row, col);
        }
        return col;

    }

    public static int moveDown(int[][] data, JTextArea[][] text,int[][] block, int row, int col){
        if(fall(data, block, row, col)){
            clear(data, text, block, row, col);
            row++;
            draw(data, text, block, row, col);
        }
        return row;
    }
}
